#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdarg.h>
// gcc -fPIC -shared -o lib_math.so lib_math.c

#define and &&
#define or ||

#define PI 3.14159265
struct Point_2{
    int x;
    int y;
};

struct Point_2_d{
    double x;
    double y;
};

float angle_hand(int x1, int y1, int x2, int y2);
float *position(float *angle, float *y1,float *y2);
struct Point_2 сenter_Coordinate(int n, ...);
struct Point_2 static_сenter_coordinate(int x, int y,int x1,int y1,int x2,int y2);
int filter_angle(int angle, double k, float limit);
struct Point_2_d rotation_points_2(int ox, int oy,int px,int py,int angle);

float hand_angle(int x_1, int y_1, int x_2, int y_2){
    float cof = 0.1;
    float cof_2 = 0.001;
    float x1 = x_1 + cof;
    float y1 = y_1 + cof;
    float x2 = x_2 + cof + cof_2;
    float y2 = y_2 + cof + cof_2;
    float k = (y2-y1)/(x2-x1);
    float b = ((x2*y1)-(y2*x1))/(x2-x1);
    if (b!=0 and k!=0){

        float angle = atan((b/k)/b)* 180.0 / PI;
        angle = *position(&angle,&y1,&y2);
        return roundf(angle);
    }
    else{
        return 0.0;
    }
}

/*
float *position(float *angle, float *y1,float *y2){
    if (*y1>*y2)
        if (*angle>=0)
            *angle = 90.0-*angle;
        else
            *angle= abs(*angle)+ 90.0;
    else
        if (*angle>=0)
            *angle= abs(*angle)+ 180.0;
        else
            *angle = 270.0+abs(*angle);
    return angle;
}
*/

float *position(float *angle, float *y1,float *y2){
    if (*y1>*y2)
        if (*angle<=0)
            *angle = 90 + *angle;
        else
            *angle = 90 + *angle;
    else
        if (*angle>=0)
            *angle = 270.0 + abs(*angle);
        else
            *angle= 270 -abs(*angle);
    return angle;
}

struct Point_2_d rotation_points_2(int ox, int oy,int px,int py,int angle){
    double angle_d = (angle*PI)/180;
    // angle = roundf(angle);
    double oxd = ox + cos(angle_d) * (px - ox) - sin(angle_d) * (py - oy);
    double oyd = oy + sin(angle_d) * (px - ox) + cos(angle_d) * (py - oy);
    struct Point_2_d point_2 = {.x = oxd, .y = oyd};
    return point_2;
}

struct Point_2 сenter_Coordinate(int n, ...){
    struct Point_2 point_2 = {.x=-1, .y=-1};
    int center_x = 0;
    int center_y = 0;
    if (n%2 == 0){
        va_list factor;
        va_start(factor, n);
        for(int i=0;i<n; i++)
        {
            if ((i%2 == 0) or (i == 0)){
                center_x += va_arg(factor, int);
            }
            else {
                center_x += va_arg(factor, int);
            }
        }
        n/=2;
        point_2.x = center_x/n;
        point_2.y = center_y/n;
        va_end(factor);
    }
    return point_2;
}

struct Point_2 static_сenter_coordinate(int x, int y,int x1,int y1,int x2,int y2){
    struct Point_2 point_2 = {.x=(x+x1+y2)/3, .y=(y+y1+y2)};

    return point_2;
}

int filter_angle(int angle, double k, float limit){
    static float old_angle = 0;
    if ((angle>=old_angle-limit) and (angle<=old_angle+limit)){
        old_angle += abs((angle-old_angle))*k;
        return old_angle;
    }
    else {
        old_angle = angle;
        return angle;
    }

}
